<?php
namespace BP\DA;
// require_once("java/io/InputStream.php");
// require_once("java/io/Reader.php");
// require_once("java/math/BigDecimal.php");
// require_once("java/net/URL.php");
// require_once("java/sql/Array.php");
// require_once("java/sql/Blob.php");
// require_once("java/sql/Clob.php");
// require_once("java/sql/Connection.php");
// require_once("java/sql/Date.php");
// require_once("java/sql/NClob.php");
// require_once("java/sql/PreparedStatement.php");
// require_once("java/sql/Ref.php");
// require_once("java/sql/RowId.php");
// require_once("java/sql/SQLException.php");
// require_once("java/sql/SQLXML.php");
// require_once("java/sql/Time.php");
// require_once("java/sql/Timestamp.php");
// require_once("java/util/Calendar.php");
// require_once("java/util/HashMap.php");
// require_once("java/util/LinkedList.php");
// require_once("java/util/List.php");
// require_once("java/util/Map.php");
class NamedParameterStatement //extends \PDOStatement
// extends PreparedStatementWrapper 
{
	protected static $nameIndexCache;	// HashMap<String, Map<String, List<Integer>>>
	protected static $parsedSqlCache;	// HashMap<String, String>
	protected $parsedSql;	// String
	protected $nameIndexMap;	// Map<String, List<Integer>>
	public $ps;
	public static function __staticinit() { // static class members
		self::$nameIndexCache = []; //
		self::$parsedSqlCache = []; //
	}
	public static function constructor__Connection_String ($conn, $sql) // [Connection conn, String sql]
	{
		$me = new self();
		if (array_key_exists($sql, self::$nameIndexCache))
		{
			$me->nameIndexMap = self::$nameIndexCache[$sql];
			$me->parsedSql = self::$parsedSqlCache[$sql];
		}
		else
		{
			$me->nameIndexMap = []; //
			$me->parsedSql = NamedParameterStatement::parseNamedSql($sql, $me->nameIndexMap);
// 			self::$nameIndexCache->put($sql, $me->nameIndexMap);
// 			self::$parsedSqlCache->put($sql, $me->parsedSql);
			self::$nameIndexCache[$sql] = $me->nameIndexMap;
			self::$parsedSqlCache[$sql]= $me->parsedSql;
		}
		$me->ps = $conn->prepare($me->parsedSql);
		return $me;
	}
	protected function getIndexes ($name) // [String name]
	{
		$indexes = $this->nameIndexMap->get($name);
		if (($indexes == NULL))
		{
			throw new \Exception(("Parameter not found: " . $name));
		}
		return $indexes;
	}
	protected static function parseNamedSql ($sql, $nameIndexMap) // [String sql, Map<String, List<Integer>> nameIndexMap]
	{
	    $length = strlen($sql);
		$parsedSql = '';
		$inSingleQuote =  FALSE ;
		$inDoubleQuote =  FALSE ;
		$index = 1;
		for ($i = 0; ($i < $length); ++$i) 
		{
// 			$c = $sql->charAt($i);
		    $c = substr($sql, $i, 1);
			
			if ($inSingleQuote)
			{
				if (($c . '\''))
				{
					$inSingleQuote =  FALSE ;
				}
			}
			else
				if ($inDoubleQuote)
				{
					if (($c . '"'))
					{
						$inDoubleQuote =  FALSE ;
					}
				}
				else
				{
					if (($c . '\''))
					{
						$inSingleQuote =  TRUE ;
					}
					else
						if (($c . '"'))
						{
							$inDoubleQuote =  TRUE ;
						}
						else
							if (((($c . ':') && (($i + 1) < $length)) && $Character->isJavaIdentifierStart($sql->charAt(($i + 1)))))
							{
								$j = ($i + 2);
								while ((($j < $length) && $Character->isJavaIdentifierPart($sql->charAt($j)))) 
								{
									++$j;
								}
								$name = $sql->substring(($i + 1), $j);
								$c = '?';
								$i += $name->length();
								$indexList = $nameIndexMap->get($name);
								if (($indexList == NULL))
								{
									$indexList = []; //
									$nameIndexMap->put($name, $indexList);
								}
								$indexList->add($index);
								++$index;
							}
				}
			$parsedSql.=($c);
		}
		return $parsedSql;
	}
	public function setArray ($name, $value) // [String name, Array value]
	{
		foreach ($this->getIndexes($name) as $index) 		{
			$this->ps->setArray($index, $value);
		}
	}
	public function setAsciiStream_String_InputStream ($name, $value) // [String name, InputStream value]
	{
		foreach ($this->getIndexes($name) as $index) 		{
			$this->ps->setAsciiStream($index, $value);
		}
	}
	public function setAsciiStream_String_InputStream_I ($name, $value, $length) // [String name, InputStream value, int length]
	{
		foreach ($this->getIndexes($name) as $index) 		{
			$this->ps->setAsciiStream($index, $value, $length);
		}
	}
	public function setBigDecimal ($name, $value) // [String name, BigDecimal value]
	{
		foreach ($this->getIndexes($name) as $index) 		{
			$this->ps->setBigDecimal($index, $value);
		}
	}
	public function setBinaryStream_String_InputStream ($name, $value) // [String name, InputStream value]
	{
		foreach ($this->getIndexes($name) as $index) 		{
			$this->ps->setBinaryStream($index, $value);
		}
	}
	public function setBinaryStream_String_InputStream_I ($name, $value, $length) // [String name, InputStream value, int length]
	{
		foreach ($this->getIndexes($name) as $index) 		{
			$this->ps->setBinaryStream($index, $value, $length);
		}
	}
	public function setBinaryStream_String_InputStream_L ($name, $value, $length) // [String name, InputStream value, long length]
	{
		foreach ($this->getIndexes($name) as $index) 		{
			$this->ps->setBinaryStream($index, $value, $length);
		}
	}
	public function setBlob_String_Blob ($name, $value) // [String name, Blob value]
	{
		foreach ($this->getIndexes($name) as $index) 		{
			$this->ps->setBlob($index, $value);
		}
	}
	public function setBlob_String_InputStream ($name, $value) // [String name, InputStream value]
	{
		foreach ($this->getIndexes($name) as $index) 		{
			$this->ps->setBlob($index, $value);
		}
	}
	public function setBlob_String_InputStream_L ($name, $value, $length) // [String name, InputStream value, long length]
	{
		foreach ($this->getIndexes($name) as $index) 		{
			$this->ps->setBlob($index, $value, $length);
		}
	}
	public function setBoolean ($name, $value) // [String name, boolean value]
	{
		foreach ($this->getIndexes($name) as $index) 		{
			$this->ps->setBoolean($index, $value);
		}
	}
	public function setByte ($name, $value) // [String name, byte value]
	{
		foreach ($this->getIndexes($name) as $index) 		{
			$this->ps->setByte($index, $value);
		}
	}
	public function setBytes ($name, $value) // [String name, byte[] value]
	{
		foreach ($this->getIndexes($name) as $index) 		{
			$this->ps->setBytes($index, $value);
		}
	}
	public function setCharacterStream_String_Reader ($name, $value) // [String name, Reader value]
	{
		foreach ($this->getIndexes($name) as $index) 		{
			$this->ps->setCharacterStream($index, $value);
		}
	}
	public function setCharacterStream_String_Reader_I ($name, $value, $length) // [String name, Reader value, int length]
	{
		foreach ($this->getIndexes($name) as $index) 		{
			$this->ps->setCharacterStream($index, $value, $length);
		}
	}
	public function setCharacterStream_String_Reader_L ($name, $value, $length) // [String name, Reader value, long length]
	{
		foreach ($this->getIndexes($name) as $index) 		{
			$this->ps->setCharacterStream($index, $value, $length);
		}
	}
	public function setClob_String_Clob ($name, $value) // [String name, Clob value]
	{
		foreach ($this->getIndexes($name) as $index) 		{
			$this->ps->setClob($index, $value);
		}
	}
	public function setClob_String_Reader ($name, $value) // [String name, Reader value]
	{
		foreach ($this->getIndexes($name) as $index) 		{
			$this->ps->setClob($index, $value);
		}
	}
	public function setClob_String_Reader_L ($name, $value, $length) // [String name, Reader value, long length]
	{
		foreach ($this->getIndexes($name) as $index) 		{
			$this->ps->setClob($index, $value, $length);
		}
	}
	public function setDate_String_Date ($name, $value) // [String name, Date value]
	{
		foreach ($this->getIndexes($name) as $index) 		{
			$this->ps->setDate($index, $value);
		}
	}
	public function setDate_String_Date_Calendar ($name, $value, $cal) // [String name, Date value, Calendar cal]
	{
		foreach ($this->getIndexes($name) as $index) 		{
			$this->ps->setDate($index, $value, $cal);
		}
	}
	public function setDouble ($name, $value) // [String name, double value]
	{
		foreach ($this->getIndexes($name) as $index) 		{
			$this->ps->setDouble($index, $value);
		}
	}
	public function setFloat ($name, $value) // [String name, float value]
	{
		foreach ($this->getIndexes($name) as $index) 		{
			$this->ps->setFloat($index, $value);
		}
	}
	public function setInt ($name, $value) // [String name, int value]
	{
		foreach ($this->getIndexes($name) as $index) 		{
			$this->ps->setInt($index, $value);
		}
	}
	public function setLong ($name, $value) // [String name, long value]
	{
		foreach ($this->getIndexes($name) as $index) 		{
			$this->ps->setLong($index, $value);
		}
	}
	public function setNCharacterStream_String_Reader ($name, $value) // [String name, Reader value]
	{
		foreach ($this->getIndexes($name) as $index) 		{
			$this->ps->setNCharacterStream($index, $value);
		}
	}
	public function setNCharacterStream_String_Reader_L ($name, $value, $length) // [String name, Reader value, long length]
	{
		foreach ($this->getIndexes($name) as $index) 		{
			$this->ps->setNCharacterStream($index, $value, $length);
		}
	}
	public function setNClob_String_NClob ($name, $value) // [String name, NClob value]
	{
		foreach ($this->getIndexes($name) as $index) 		{
			$this->ps->setNClob($index, $value);
		}
	}
	public function setNClob_String_Reader ($name, $value) // [String name, Reader value]
	{
		foreach ($this->getIndexes($name) as $index) 		{
			$this->ps->setNClob($index, $value);
		}
	}
	public function setNClob_String_Reader_L ($name, $value, $length) // [String name, Reader value, long length]
	{
		foreach ($this->getIndexes($name) as $index) 		{
			$this->ps->setNClob($index, $value, $length);
		}
	}
	public function setNString ($name, $value) // [String name, String value]
	{
		foreach ($this->getIndexes($name) as $index) 		{
			$this->ps->setNString($index, $value);
		}
	}
	public function setNull ($name, $sqlType) // [String name, int sqlType]
	{
		foreach ($this->getIndexes($name) as $index) 		{
			$this->ps->setNull($index, $sqlType);
		}
	}
	public function setObject_String_Object ($name, $value) // [String name, Object value]
	{
		foreach ($this->getIndexes($name) as $index) 		{
			$this->ps->setObject($index, $value);
		}
	}
	public function setObject_String_Object_I ($name, $value, $targetSqlType) // [String name, Object value, int targetSqlType]
	{
		foreach ($this->getIndexes($name) as $index) 		{
			$this->ps->setObject($index, $value, $targetSqlType);
		}
	}
	public function setObject_String_Object_I_I ($name, $value, $targetSqlType, $scaleOrLength) // [String name, Object value, int targetSqlType, int scaleOrLength]
	{
		foreach ($this->getIndexes($name) as $index) 		{
			$this->ps->setObject($index, $value, $targetSqlType, $scaleOrLength);
		}
	}
	public function setRef ($name, $value) // [String name, Ref value]
	{
		foreach ($this->getIndexes($name) as $index) 		{
			$this->ps->setRef($index, $value);
		}
	}
	public function setRowId ($name, $value) // [String name, RowId value]
	{
		foreach ($this->getIndexes($name) as $index) 		{
			$this->ps->setRowId($index, $value);
		}
	}
	public function setShort ($name, $value) // [String name, short value]
	{
		foreach ($this->getIndexes($name) as $index) 		{
			$this->ps->setShort($index, $value);
		}
	}
	public function setSQLXML ($name, $value) // [String name, SQLXML value]
	{
		foreach ($this->getIndexes($name) as $index) 		{
			$this->ps->setSQLXML($index, $value);
		}
	}
	public function setString ($name, $value) // [String name, String value]
	{
		foreach ($this->getIndexes($name) as $index) 		{
			$this->ps->setString($index, $value);
		}
	}
	public function setTime_String_Time ($name, $value) // [String name, Time value]
	{
		foreach ($this->getIndexes($name) as $index) 		{
			$this->ps->setTime($index, $value);
		}
	}
	public function setTime_String_Time_Calendar ($name, $value, $cal) // [String name, Time value, Calendar cal]
	{
		foreach ($this->getIndexes($name) as $index) 		{
			$this->ps->setTime($index, $value, $cal);
		}
	}
	public function setTimestamp_String_Timestamp ($name, $value) // [String name, Timestamp value]
	{
		foreach ($this->getIndexes($name) as $index) 		{
			$this->ps->setTimestamp($index, $value);
		}
	}
	public function setTimestamp_String_Timestamp_Calendar ($name, $value, $cal) // [String name, Timestamp value, Calendar cal]
	{
		foreach ($this->getIndexes($name) as $index) 		{
			$this->ps->setTimestamp($index, $value, $cal);
		}
	}
	public function setUnicodeStream ($name, $value, $length) // [String name, InputStream value, int length]
	{
		foreach ($this->getIndexes($name) as $index) 		{
			$this->ps->setUnicodeStream($index, $value, $length);
		}
	}
	public function setURL ($name, $value) // [String name, URL value]
	{
		foreach ($this->getIndexes($name) as $index) 		{
			$this->ps->setURL($index, $value);
		}
	}
}
NamedParameterStatement::__staticinit(); // initialize static vars for this class on load
?>
